#include <iostream>

//int&是一个整体，表示引用变量,和取值符号&不是一个意思
//引用必须初始化，int& b;只定义，不赋值是不可以的。
void Test01(){
    int a = 8;
    //不可以这么写：int& b;
    int& ref = a;
    ref = 9;
    std::cout << "a=" << a << std::endl;
}

void Test02(){
    int a = 8;
	int& ref = a;

	//引用和被引用对象是用一个意思，所以地址也一样（因此引用是一个便于程序员操作的东西）
	//并不存在在栈内存中创建一个新的变量叫做ref，然后给它一个地址
	std::cout << "a的地址:" << &a << std::endl;
	std::cout << "ref的地址:" << &ref << std::endl;

	//指针变量是一个新的变量，是需要在栈内存中为其分配内存的
	//指针变量是一个4个字节大小的int值(或者8个字节，看编译器的设计)
	int b = 8;
	int* ptr = &a;
	std::cout << "b的地址:" << &b << std::endl;
	std::cout << "ptr的地址:" << &ptr << std::endl;
}

//引用就是绑定关系！
//引用就是别名，和原来的变量是一样的，
//就像桌子和desk指的是同一样东西，只是名字不一样
void swap(int& a, int& b){
    int temp = a;
    a = b;
    b = temp;
}

/**
 * 引用作为函数参数
 */
void Test03(){
    int a = 8, b = 10;
    swap(a, b);
    std::cout << "a的值是:" << a << std::endl;
    std::cout << "b的值是:" << b << std::endl;
}

void swap2(int& a, int& b){
    std::cout << "swap2函数中a的地址是:" << &a << std::endl;
    std::cout << "swap2函数中b的地址是:" << &b << std::endl;
    int temp = a;
    a = b;
    b = temp;
}
//打印地址观察，地址一样的话，两个变量在内存中就是一样的，
//只是对于程序员来说，有两个名字罢了
void Test04(){
    int a = 8, b = 10;
    std::cout << "函数外面a的地址是:" << &a << std::endl;
    std::cout << "函数外面b的地址是:" << &b << std::endl;
    swap2(a, b);
}

/**
 * 值传递，会复制一份变量
 */
void swap3(int a, int b){
    std::cout << "swap3函数中a的地址是:" << &a << std::endl;
    std::cout << "swap3函数中b的地址是:" << &b << std::endl;
    int temp = a;
    a = b;
    b = temp;
}

void Test05(){
    int a = 8, b = 10;
    std::cout << "函数外面a的地址是:" << &a << std::endl;
    std::cout << "函数外面b的地址是:" << &b << std::endl;
    swap3(a, b);
}


/**
 * 引用测试
 */
int main(){

    // Test04();

    Test05();

    return 0;
}